package com.college.common.utils.json;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;

import java.util.*;

public class JsonSortUtil {

    public static void main(String[] args) {
        String s = "{\"tt\":\"ttt\", \"data\":{\"liveInfo\":{\"createTime\":\"2021-11-19 12:12:20\",\"idCardBackImge\":\"sdfsdfsdfsd\",\"faceImge\":\"65465464\",\"idCardFrontImge\":\"sjdfosjdfj\"},\"contactsInfo\":{\"contactOneName\":\"杨老爷\",\"contactOneType\":501,\"contactTwoType\":601,\"contactOneMobile\":\"12345678987\",\"contactTwoMobile\":\"79846512332\",\"contactTwoName\":\"刘先生\"},\"orderType\":1,\"orderNo\":\"12345678910\",\"userBaseInfo\":{\"loanUsageType\":411,\"inCome\":\"5000\",\"educationType\":255,\"houseType\":101,\"mobile\":\"15236294846\",\"name\":\"杨艺飞\",\"currentAddress\":\"北京市 北京市 昌平区 天露园小区二区\",\"marriageType\":202},\"identityInfo\":{\"issueAgency\":\"漯河市郾城区公安局\",\"periodValidityDate\":\"2017.07.16-2027.07.16\",\"nation\":\"汉\",\"sex\":2,\"name\":\"杨艺飞\",\"idNum\":\"411123199101189577\",\"identityAddress\":\"河南省漯河市郾城区商桥镇\"},\"positionInfo\":{\"applypos\":\"北京市昌平区龙泽园街道\",\"applyX\":\"456654\",\"applyY\":\"sdfsdf\",\"applytim\":\"2021-11-19 12:12:23\"},\"companyInfo\":{\"companyAddress\":\"北京市 北京市 海淀区 西北旺地区\",\"companyName\":\"北京网众共创\",\"companyTel\":\"32145678965\",\"companyNatureType\":304},\"applyInfo\":{\"orderTime\":\"2021-11-11 10:12:20\",\"applyPeriodNum\":12,\"applyAmount\":500000,\"applyPeriodNumUnit\":2},\"deviceInfo\":{\"lanAddress\":\"10.12.23.152\",\"ip\":\"172.12.23.152\",\"gsmImei\":\"gsmImei\",\"serviceName\":\"中国 移动\",\"mem\":\"512\",\"cdmaMeid\":\"cdmaMeid\",\"osType\":\"ios\",\"imei\":\"imei\",\"deviceModel\":\"P50\",\"networkType\":\"networkType\",\"dataSource\":\"datasource\",\"deviceBrand\":\"华为\",\"isSimulator\":\"否\"}},\"sign\":\"uQnnyrX2wUVWjSrMYQxytC+7uK4hwm2uZxcXt5uFiN8ASg2QuFuWk3IXlnnoF1i8rpJrAVDW4PZc\\r\\nz57wcA9yRP0ylthzRPedzpUlrxUD08ajInc7LZDQlIz26tCs8Hb3HjCouO/7ecH6WgGKZg5hb/Vi\\r\\n/dOFqmtYWjWxnVyP0qE=\"}";
        System.out.println(JsonSortUtil.jsonObjConverSortStr(s));
    }

    public static String jsonObjConverSortStr(String jsonText) {
        StringBuffer returnBuStr = new StringBuffer();
        jsonObjParseRecur(returnBuStr, jsonText, true);
        return returnBuStr.toString();
    }

    private static void jsonObjParseRecur(StringBuffer returnBuStr, String jsonText, boolean isComplexObj) {
        JSONObject jsonObj = JSONObject.parseObject(jsonText);
        Iterator<String> keys = jsonObj.keySet().iterator();

        // 局部key集合 并排序
        Set<String> keySetSort = new HashSet<>();
        while (keys.hasNext()) {
            String key = keys.next();
            keySetSort.add(key);
        }
        List<String> sortList = new ArrayList<>(keySetSort);
        Collections.sort(sortList);

        // 开始遍历 递归解析
        for (String key : sortList) {
            if (returnBuStr.length() == 0 || isComplexObj) {
                returnBuStr.append(key).append("=");
                isComplexObj = false;
            } else {
                returnBuStr.append("&").append(key).append("=");
            }

            StringBuffer sbSubArr = new StringBuffer();
            if (jsonObj.get(key) instanceof JSONArray) { // 类型 - JSONArray
                JSONArray jsonArray = jsonObj.getJSONArray(key);
                returnBuStr.append("[");

                for (int i = 0; i < jsonArray.size(); i++) {
                    Object obj = jsonArray.get(i);

                    // JSONArray - 依然是数组元素
                    if (obj instanceof JSONArray) {
                        String jsonArrayObjString = obj.toString();
                        if (sbSubArr.length() == 0) {
                            sbSubArr.append(jsonArrayObjString);
                        } else {
                            sbSubArr.append(",").append(jsonArrayObjString);
                        }
                        continue;
                    }

                    // JSONArray - jsonObj复杂对象
                    if (obj instanceof JSONObject) {
                        JSONObject jsonObjTemp = jsonArray.getJSONObject(i);
                        if (i == 0) {
                            sbSubArr.append("{");
                            jsonObjParseRecur(sbSubArr, jsonObjTemp.toString(), true);
                            sbSubArr.append("}");
                        } else {
                            sbSubArr.append(",{");
                            jsonObjParseRecur(sbSubArr, jsonObjTemp.toString(), true);
                            sbSubArr.append("}");
                        }
                    }

                    // JSONArray - 普通元素
                    if (!(obj instanceof JSONArray) && !(obj instanceof JSONObject)) {
                        if (sbSubArr.length() == 0) {
                            sbSubArr.append(obj.toString());
                        } else {
                            sbSubArr.append(",").append(obj.toString());
                        }
                    }
                }
                returnBuStr.append(sbSubArr);
                returnBuStr.append("]");
            } else if (jsonObj.get(key) instanceof JSONObject) { // 类型 - JSONObject
                returnBuStr.append("{");
                jsonObjParseRecur(returnBuStr, jsonObj.getString(key), true);
                returnBuStr.append("}");

            } else { // 以上两种情况都不是的情况下，则为普通元素
                returnBuStr.append(jsonObj.get(key).toString());
            }
        }
    }

    public static JSONObject getSortJson(JSONObject json) {
        if (Objects.isNull(json)) {
            return new JSONObject();
        }
        Set<String> keySet = json.keySet();
        SortedMap<String, Object> map = new TreeMap<>();
        for (String key:keySet) {
            Object value = json.get(key);
            if (Objects.nonNull(value) && value instanceof JSONArray) {
                JSONArray array = json.getJSONArray(key);
                JSONArray jsonArray = new JSONArray(new LinkedList<>());
                for (int i=0;i<array.size();i++) {
                    JSONObject sortJson = getSortJson(array.getJSONObject(i));
                    jsonArray.add(sortJson);
                }
                map.put(key, jsonArray);
            } else if (Objects.nonNull(value) && value instanceof JSONObject) {
                JSONObject sortJson = getSortJson(json.getJSONObject(key));
                map.put(key, sortJson);
            } else {
                map.put(key, value);
            }
        }
        return new JSONObject(map);
    }
}